package com.yzd.learnjava.concurrency;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.yzd.learnjava.util.Generated;
import com.yzd.learnjava.util.Print;
import com.yzd.learnjava.util.RandomGenerator;

public abstract class Tester<C> {
	static int testReps = 1;
	static int testCycles = 1000;
	static int containerSize = 1000;
	abstract C containerInitializer();
	abstract void startReadersAndWriters();
	C testContainer;
	String testId;
	int nReaders ;
	int nWriters;
	volatile long readResult ;
	volatile long readTime ;
	volatile long writeTime;
	
	CountDownLatch endLatch;
	static ExecutorService exec = Executors.newCachedThreadPool();
	Integer[] writeData;
	
	Tester(String testId , int nReaders , int nWriters){
		this.testId = testId + " " + nReaders + "r " + nWriters + "w";
		this.nReaders = nReaders;
		this.nWriters = nWriters;
		writeData = Generated.array(Integer.class, new RandomGenerator.Integer(), containerSize);
		for(int i = 0 ; i < testReps; i++) {
			runTest();
			readTime = 0;
			writeTime = 0;
		}
	}
	
	void runTest() {
		endLatch = new CountDownLatch(nReaders + nWriters);
		testContainer = containerInitializer();
		startReadersAndWriters();
		try {
			endLatch.await();
		} catch (InterruptedException e) {
			Print.print("endLatch interrupted");
			e.printStackTrace();
		}
		System.out.printf("%-27s %14d %14d\n", testId, readTime, writeTime);
		if(readTime != 0 && writeTime != 0) {
			System.out.printf("%-27s %14d\n", "readTime + writeTime =", readTime + writeTime);
		}
	}
	abstract class TestTask implements Runnable{
		abstract void test();
		abstract void putResults();
		long duration ;
		public void run() {
			long startTime = System.nanoTime();
			test();
			duration = System.nanoTime() - startTime;
			synchronized (Tester.this) {
				putResults();
			}
			endLatch.countDown();
		}
	}
	
	public static void initMain(String[] args) {
		System.out.printf("%-27s %14s %14s\n", "Type", "Read time", "Write time");
	}

}




































